package com.ruoyi.file.service.impl;

import com.ruoyi.common.constant.RedisEnum;
import com.ruoyi.common.core.redis.CommonRedisService;
import com.ruoyi.common.utils.StringUtils;
import com.ruoyi.file.service.IFileService;
import org.springframework.context.annotation.Lazy;
import org.springframework.stereotype.Service;
import com.qiniu.common.QiniuException;
import com.qiniu.common.Zone;
import com.qiniu.storage.BucketManager;
import com.qiniu.storage.Configuration;
import com.qiniu.storage.model.FileInfo;
import com.qiniu.util.Auth;
import com.qiniu.util.StringMap;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import java.io.UnsupportedEncodingException;
import java.net.URLEncoder;
import java.util.Optional;

@Service
public class FileServiceImpl implements IFileService {

    @Value("${upload.accessKey}")
    String accessKey;

    @Value("${upload.secretKey}")
    String secretKey;

    @Value("${upload.domainOfBucketCommon}")
    String domain;

    @Value("${upload.bucketCommon}")
    String bucket_common;

    @Value("${upload.bucket}")
    String bucket;

    public final Long TOKEN_EXPIRE_SECONDS = 3600L;

    @Autowired
    private CommonRedisService redisService;

    @Override
    public String getUpToken(String bucket, long expireSeconds) {
        String key = RedisEnum.QINIU_UP_TOKEN.getKey() + bucket;
        Optional<String> op = redisService.getAsOptional(key);
        if(op.isPresent()) {
            return op.get();
        }
        synchronized (this) {
            op = redisService.getAsOptional(key);
            if(op.isPresent()) {
                return op.get();
            }
            String token = genUpToken(bucket);
            if(StringUtils.isNotBlank(token)) {
                redisService.put(key, token, TOKEN_EXPIRE_SECONDS);
            }
            return token;
        }
    }

    private String genUpToken(String bucket){
        Auth auth = Auth.create(accessKey, secretKey);
        StringMap putPolicy = new StringMap();
        putPolicy.put("returnBody", "{\"key\":\"$(key)\",\"hash\":\"$(etag)\",\"bucket\":\"$(bucket)\",\"fsize\":$(fsize)}");
        return auth.uploadToken(bucket, null, TOKEN_EXPIRE_SECONDS, putPolicy);
    }

    @Override
    public String getUrl(String key, String type, long expireSeconds) {
        String encodedFileName = null;
        try {
            encodedFileName = URLEncoder.encode(key, "utf-8");
        } catch (UnsupportedEncodingException e) {
            e.printStackTrace();
        }
        if("common".equals(type)){
            return String.format("%s/%s", domain, encodedFileName);
        }else{
            String publicUrl = String.format("%s/%s", domain, encodedFileName);
            Auth auth = Auth.create(accessKey, secretKey);
            return auth.privateDownloadUrl(publicUrl, expireSeconds);
        }
    }

    @Override
    public FileInfo getFileInfo(String key, String bucket) throws QiniuException{
        Configuration cfg = new Configuration(Zone.zone0());
        Auth auth = Auth.create(accessKey, secretKey);
        BucketManager bucketManager = new BucketManager(auth, cfg);
        FileInfo fileInfo = bucketManager.stat(bucket, key);
        return fileInfo;
    }

    @Override
    public void move(String fromBucket, String toBucket, String fromKey, String toKey) throws QiniuException{
        Configuration cfg = new Configuration(Zone.zone0());
        Auth auth = Auth.create(accessKey, secretKey);
        BucketManager bucketManager = new BucketManager(auth, cfg);
        bucketManager.move(fromBucket, fromKey, toBucket, toKey);
    }

    @Override
    public void copy(String fromBucket, String toBucket, String fromKey, String toKey) throws QiniuException{
        Configuration cfg = new Configuration(Zone.zone0());
        Auth auth = Auth.create(accessKey, secretKey);
        BucketManager bucketManager = new BucketManager(auth, cfg);
        bucketManager.copy(fromBucket, fromKey, toBucket, toKey);
    }

    @Override
    public void delete(String key, String bucket){
        try{
            Configuration cfg = new Configuration(Zone.zone0());
            Auth auth = Auth.create(accessKey, secretKey);
            BucketManager bucketManager = new BucketManager(auth, cfg);
            bucketManager.delete(bucket, key);
        }catch (Exception e) {
            e.printStackTrace();
        }
    }
}
